"""
MDB Interface 接口生成器

根据 mdb_interface 项目的 JSON 文件生成对应的 .pyi 文件
"""

import json
import re
from pathlib import Path
from typing import Dict, List, Any, Optional


class MDBInterfaceGenerator:
    """MDB Interface 接口生成器"""

    def __init__(self, mdb_interface_root: str = "subprojects/mdb_interface"):
        # 确保 mdb_interface_root 是相对于当前工作目录的绝对路径
        if not Path(mdb_interface_root).is_absolute():
            # 尝试从多个可能的位置查找
            current_dir = Path.cwd()
            possible_paths = [
                current_dir / mdb_interface_root,
                current_dir.parent / mdb_interface_root,
                current_dir.parent.parent / mdb_interface_root,
                # 从项目根目录开始查找
                current_dir.parent.parent.parent / mdb_interface_root,
                # 从构建目录的上级目录开始查找
                current_dir.parent.parent.parent.parent / mdb_interface_root,
            ]

            for path in possible_paths:
                if path.exists():
                    self.mdb_interface_root = path
                    print(f"找到 mdb_interface 目录: {path}")
                    break
            else:
                # 如果都找不到，使用默认路径
                self.mdb_interface_root = Path(mdb_interface_root)
                print(
                    f"警告: 未找到 mdb_interface 目录，使用默认路径: {self.mdb_interface_root}"
                )
        else:
            self.mdb_interface_root = Path(mdb_interface_root)

        self.type_mappings = {
            "U32": "int",
            "U64": "int",
            "I32": "int",
            "I64": "int",
            "String": "str",
            "Boolean": "bool",
            "Float": "float",
            "Double": "float",
            "Object": "Any",
            "Array": "List",
            "Map": "Dict",
        }

    def generate_interface_pyi(
        self, config_file: str, output_dir: str = "task_service"
    ) -> Dict[str, str]:
        """
        根据配置文件生成接口 pyi 文件

        Args:
            config_file: 配置文件路径
            output_dir: 输出目录

        Returns:
            生成的文件字典 {文件名: 内容}
        """
        # 读取配置文件
        config_path = Path(config_file)
        if not config_path.exists():
            raise FileNotFoundError(f"配置文件不存在: {config_path}")

        print(f"读取配置文件: {config_path}")
        with open(config_path, "r", encoding="utf-8") as f:
            config = json.load(f)

        generated_files = {}

        # 处理每个 mdb 接口
        for interface_config in config.get("mdb_interfaces", []):
            interface_path = interface_config["interface_path"]
            interface_name = interface_config["interface_name"]
            local_name = interface_config["local_name"]

            # 读取 mdb 接口 JSON 文件
            mdb_file = self.mdb_interface_root / "json" / "intf" / interface_path
            print(f"查找 MDB 接口文件: {mdb_file}")

            if not mdb_file.exists():
                print(f"警告: MDB 接口文件不存在: {mdb_file}")
                continue

            with open(mdb_file, "r", encoding="utf-8") as f:
                mdb_data = json.load(f)

            # 生成 pyi 文件内容
            pyi_content = self._generate_pyi_content(
                interface_name, local_name, mdb_data[interface_name], config
            )

            # 保存文件
            output_file = f"{local_name.lower()}.pyi"
            generated_files[output_file] = pyi_content

        # 生成自定义枚举
        for enum_config in config.get("custom_enums", []):
            enum_content = self._generate_enum_pyi(enum_config)
            enum_file = f"{enum_config['name'].lower()}.pyi"
            generated_files[enum_file] = enum_content

        return generated_files

    def _generate_pyi_content(
        self,
        interface_name: str,
        local_name: str,
        interface_data: Dict[str, Any],
        config: Dict[str, Any],
    ) -> str:
        """生成接口 pyi 文件内容"""

        # 提取属性信息
        properties = interface_data.get("properties", {})

        # 生成 pyi 内容
        lines = [
            f'"""',
            f"{interface_name} 接口定义",
            f"",
            f"此文件由 mdb_interface 自动生成",
            f'"""',
            f"",
            f"from typing import Any, List, Dict, Optional",
            f"",
            f"",
            f"class {local_name}:",
            f'    """{interface_name} 接口"""',
            f"    ",
        ]

        # 添加属性
        for prop_name, prop_data in properties.items():
            prop_type = self._convert_mdb_type(prop_data["baseType"])
            prop_desc = prop_data.get("description", "")

            # 处理枚举类型
            if "enum" in prop_data:
                enum_values = prop_data["enum"]
                enum_name = f"{prop_name}Enum"
                lines.extend(
                    [
                        f"    class {enum_name}:",
                        f'        """{prop_desc}"""',
                    ]
                )
                for value in enum_values:
                    lines.append(f"        {value}: str")
                lines.append(f"    ")
                prop_type = f"{local_name}.{enum_name}"

            # 处理数组类型
            if prop_type.endswith("[]"):
                base_type = prop_type[:-2]
                prop_type = f"List[{self._convert_mdb_type(base_type)}]"

            # 添加属性定义
            lines.extend(
                [
                    f"    {prop_name}: {prop_type}",
                    f'    """{prop_desc}"""',
                    f"    ",
                ]
            )

        # 添加方法（如果有的话）
        methods = interface_data.get("methods", {})
        for method_name, method_data in methods.items():
            return_type = self._convert_mdb_type(method_data.get("returnType", "None"))
            lines.extend(
                [
                    f"    def {method_name}(self) -> {return_type}:",
                    f'        """{method_data.get("description", "")}"""',
                    f"        ...",
                    f"    ",
                ]
            )

        return "\n".join(lines)

    def _generate_enum_pyi(self, enum_config: Dict[str, Any]) -> str:
        """生成枚举 pyi 文件内容"""

        lines = [
            f'"""',
            f'{enum_config["name"]} 枚举定义',
            f"",
            f"此文件由 mdb_interface 自动生成",
            f'"""',
            f"",
            f"from enum import IntEnum",
            f"",
            f"",
            f'class {enum_config["name"]}(IntEnum):',
            f'    """{enum_config["description"]}"""',
            f"    ",
        ]

        for value_config in enum_config["values"]:
            lines.extend(
                [
                    f'    {value_config["name"]} = {value_config["value"]}',
                    f'    """{value_config["description"]}"""',
                    f"    ",
                ]
            )

        return "\n".join(lines)

    def _convert_mdb_type(self, mdb_type: str) -> str:
        """转换 MDB 类型到 Python 类型"""
        # 处理数组类型
        if mdb_type.endswith("[]"):
            base_type = mdb_type[:-2]
            return f"List[{self._convert_mdb_type(base_type)}]"

        # 处理基本类型
        return self.type_mappings.get(mdb_type, "Any")


def generate_mdb_interfaces(
    config_file: str, output_dir: str = "task_service"
) -> Dict[str, str]:
    """
    生成 MDB 接口文件

    Args:
        config_file: 配置文件路径
        output_dir: 输出目录

    Returns:
        生成的文件字典
    """
    generator = MDBInterfaceGenerator()
    generated_files = generator.generate_interface_pyi(config_file, output_dir)

    # 保存生成的文件
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    print(f"输出目录: {output_path}")
    for filename, content in generated_files.items():
        file_path = output_path / filename
        with open(file_path, "w", encoding="utf-8") as f:
            f.write(content)
        print(f"已生成: {file_path}")

    return generated_files


if __name__ == "__main__":
    import sys

    # 处理命令行参数
    if len(sys.argv) < 3:
        print(
            "用法: python mdb_interface_generator.py <config_file> <output_dir> [mdb_interface_root]"
        )
        sys.exit(1)

    config_file = sys.argv[1]
    output_dir = sys.argv[2]

    # 可选的 mdb_interface 根目录
    mdb_interface_root = None
    if len(sys.argv) > 3:
        mdb_interface_root = sys.argv[3]

    # 确保配置文件路径是相对于当前工作目录的
    if not Path(config_file).is_absolute():
        config_file = str(Path.cwd() / config_file)

    # 确保输出目录路径是相对于当前工作目录的
    if not Path(output_dir).is_absolute():
        output_dir = str(Path.cwd() / output_dir)

    generator = MDBInterfaceGenerator(mdb_interface_root)
    generated_files = generator.generate_interface_pyi(config_file, output_dir)

    # 保存生成的文件
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    print(f"输出目录: {output_path}")
    for filename, content in generated_files.items():
        file_path = output_path / filename
        with open(file_path, "w", encoding="utf-8") as f:
            f.write(content)
        print(f"已生成: {file_path}")

    print(f"总共生成 {len(generated_files)} 个文件")
